#ifndef CHAPTER18_USELESS_H_
#define CHAPTER18_USELESS_H_

#include <iostream>

using namespace std;

//interface 
class Useless
{
private:
	int n;			//number of elements
	char * pc;		//pointer to data
	static int ct;	//number of objects
	void ShowObject() const;
public:
	Useless();
	explicit Useless(int k);
	Useless(int k, char ch);
	Useless(const Useless & f);			//regular copy constructor
	Useless(Useless &&f);				//move constructor
	~Useless();
	Useless operator+(const Useless & f) const;
//need operator=() in copy and move versions
	void ShowData() const;
};

//implementation
int Useless::ct = 0;

Useless::Useless()
{
	++ct;
	n = 0;
	pc = nullptr;
	cout << "default constructor called; number of objects: " << ct << endl;
	ShowObject();
}

Useless::Useless(int k) :n(k)
{
	++ct;
	cout << "int constructor called; number of objects: " << ct << endl;
	pc = new char[n];
	ShowObject();
}

Useless::Useless(int k, char ch) :n(k)
{
	++ct;
	cout << "int, char constructor called; number of objects: " << ct << endl;
	pc = new char[n];
	for (int i = 0; i < n; i++)
		pc[i] = ch;
	ShowObject();
}

Useless::Useless(const Useless & f) :n(f.n)
{
	++ct;
	cout << "copy const called; number of objects: " << ct << endl;
	pc = new char[n];
	for (int i = 0; i < n; i++)
		pc[i] = f.pc[i];
	ShowObject();
}

Useless::Useless(Useless &&f) :n(f.n)
{
	++ct;
	cout << "move constructor called;number of objects: " << ct << endl;
	pc = f.pc;			//steal address
	f.pc = nullptr;		//give old object nothing in return
	ShowObject();
}

Useless::~Useless()
{
	cout << "destructor called; objects left: " << --ct << endl;
	cout << "deleted object:\n";
	ShowObject();
	delete[] pc;
}

Useless Useless::operator+(const Useless & f) const
{
	cout << "Entering operator+()\n";
	Useless temp = Useless(n + f.n);
	for (int i = 0; i < n; i++)
		temp.pc[i] = pc[i];
	for (int i = n; i < temp.n; i++)
		temp.pc[i] = f.pc[i - n];
	cout << "temp object:\n";
	cout << "Leaving operator+()\n";
	return temp;
}

void Useless::ShowObject() const
{
	cout << "Number of elements: " << n;
	cout << " Data address: " << (void *)pc << endl;
}

void Useless::ShowData() const
{
	if (n == 0)
		cout << "(object empty)";
	else
		for (int i = 0; i < n; i++)
			cout << pc[i];
	cout << endl;
}

#endif // !CHAPTER18_USELESS_H_

